local skel = fk.CreateSkill {
  name = "emo__luanzhang",
  tags = {Skill.Compulsory},
}

Fk:loadTranslationTable{
  ["emo__luanzhang"] = "乱章",
  [":emo__luanzhang"] = "锁定技，任意角色执行以下效果时，令其改为执行以下随机另一项："..
  "<br>1.弃置两张手牌；2.弃置装备区一张牌；3.受到一点普通伤害；4.失去一点体力；5.扣减一点体力上限；6.横置；7. 翻至背面。"..
  "<br>若为其他角色，你摸一张牌，若为你，改为你选一项执行。"..
  "<br><font color='grey'>（执行“乱章”的效果时不会再触发“乱章”）</font>",

  ["#emo__luanzhang-choice"] = "乱章：请选一项执行",
  ["#EmoLzLog"] = "%from 的 %arg 被改为 %arg2",

  ["emolz_damage"] = "受到一点普通伤害",
  ["emolz_loseHp"] = "失去一点体力",
  ["emolz_loseMaxHp"] = "扣减一点体力上限",
  ["emolz_chain"] = "横置",
  ["emolz_turnOver"] = "翻至背面",
  ["emolz_discard2hand"] = "弃置两张手牌",
  ["emolz_discard1equip"] = "弃置装备区一张牌",

  ["$emo__luanzhang1"] = "古娜拉黑暗之神，呜呵啦呼，黑魔变身！",
  ["$emo__luanzhang2"] = "古娜拉黑暗之神，呼咔啦，黑气功！",
  ["$emo__luanzhang3"] = "古娜拉黑暗之神，哒啦咕啦，黑魔传书！",
  ["$emo__luanzhang4"] = "古娜拉黑暗之神，啦妮妮娜，隐形魔法！",
  ["$emo__luanzhang5"] = "古娜拉黑暗之神，它它啦，移形魔法！",
  ["$emo__luanzhang6"] = "古娜拉黑暗之神，呼它啦，消失！",
  ["$emo__luanzhang7"] = "古娜拉黑暗之神，啦斯塔，还原！",
}

---@param player ServerPlayer
local function triggerable (player, target)
  if not player:hasSkill(skel.name) or player.room:getTag("LuanzhangProcessing") then return false end
  if target and target.dead then return false end
  return true
end

---@param player ServerPlayer
local on_use = function (self, event, target, player, data)
  local room = player.room
  local cost_data = event:getCostData(self)
  local to, exclude = cost_data.tos[1], cost_data.choice
  if type(exclude) == "string" then exclude = {exclude} end
  local all_choices = {"discard2hand", "discard1equip", "damage", "loseHp", "loseMaxHp", "chain", "turnOver"}
  local choices = table.filter(all_choices, function(choice) return not table.contains(exclude, choice) end)
  --- 筛选不能执行项
  if #table.filter(to:getCardIds("h"), function(id) return not to:prohibitDiscard(Fk:getCardById(id)) end) < 2 then
    table.removeOne(choices, "discard2hand")
  end
  if not table.find(to:getCardIds("e"), function(id) return not to:prohibitDiscard(Fk:getCardById(id)) end) then
    table.removeOne(choices, "discard1equip")
  end
  if to.maxHp <= 0 then -- 防一手洛丝特
    table.removeOne(choices, "loseMaxHp")
  end
  if to.chained then
    table.removeOne(choices, "chain")
  end
  if not to.faceup then
    table.removeOne(choices, "turnOver")
  end

  -- 删除原执行项
  local remove = table.random(exclude)
  if event == fk.DamageInflicted then
    data:preventDamage()
  elseif event == fk.BeforeCardsMove then
    -- 移动时机可能触发两项，故随机删除一项
    for _, move in ipairs(data) do
      if move.from and move.moveReason == fk.ReasonDiscard and move.from == to then
        if remove == "discard2hand" and
        #table.filter(move.moveInfo, function(info) return info.fromArea == Player.Hand end) == 2 then -- 这一步检测不可少，别删错了
          move.moveInfo = table.filter(move.moveInfo, function(info) return info.fromArea ~= Player.Hand end)
          break
        elseif remove == "discard1equip" and
        #table.filter(move.moveInfo, function(info) return info.fromArea == Player.Equip end) == 1 then
          move.moveInfo = table.filter(move.moveInfo, function(info) return info.fromArea ~= Player.Equip end)
          break
        end
      end
    end
  else
    data.prevented = true
  end

  -- 执行修改后的效果
  room:setTag("LuanzhangProcessing", true)
  room.logic:getCurrentEvent():addCleaner(function()
    room:setTag("LuanzhangProcessing", false)
  end)
  local choice = "damage"
  if to ~= player then
    choice = table.random(choices)
    room.logic:getCurrentEvent().parent:addExitFunc(function() -- 摸一张牌，延后执行
      if not player.dead then player:drawCards(1, skel.name) end
    end)
  else
    local choiceStrs = table.map(choices, function (s) return "emolz_" .. s end)
    local choiceStr = room:askToChoice(player, {skill_name = skel.name, choices = choiceStrs, prompt = "#emo__luanzhang-choice" })
    choice = choiceStr:sub(7, -1)
  end
  room:sendLog{ type = "#EmoLzLog", from = to.id, arg = "emolz_" .. remove, arg2 = "emolz_" .. choice }

  if choice == "discard2hand" then
    room:askToDiscard(to, {min_num = 2, max_num = 2, include_equip = false, skill_name = skel.name, cancelable = false})
  elseif choice == "discard1equip" then
    room:askToDiscard(to, {min_num = 1, max_num = 1, include_equip = true, skill_name = skel.name, cancelable = false, pattern = ".|.|.|equip"})
  elseif choice == "damage" then
    room:damage { to = to, damage = 1, skillName = skel.name}
  elseif choice == "loseHp" then
    room:loseHp(to, 1, skel.name)
  elseif choice == "loseMaxHp" then
    room:changeMaxHp(to, -1)
  elseif choice == "chain" then
    to:setChainState(true)
  elseif choice == "turnOver" then
    to:turnOver()
  end
end

skel:addEffect(fk.DamageInflicted, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not triggerable(player, target) then return false end
    if data.damageType == fk.NormalDamage and data.damage == 1 then
      event:setCostData(self, {choice = "damage", tos = {target} })
      return true
    end
  end,
  on_use = on_use,
})

skel:addEffect(fk.PreHpLost, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not triggerable(player, target) then return false end
    if data.num == 1 then
      event:setCostData(self, {choice = "loseHp", tos = {target} })
      return true
    end
  end,
  on_use = on_use,
})

skel:addEffect(fk.BeforeMaxHpChanged, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not triggerable(player, target) then return false end
    if data.num == -1 then
      event:setCostData(self, {choice = "loseMaxHp", tos = {target} })
      return true
    end
  end,
  on_use = on_use,
})

skel:addEffect(fk.BeforeChainStateChange, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not triggerable(player, target) then return false end
    if not target.chained then
      event:setCostData(self, {choice = "chain", tos = {target} })
      return true
    end
  end,
  on_use = on_use,
})

skel:addEffect(fk.BeforeTurnOver, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not triggerable(player, target) then return false end
    if target.faceup then
      event:setCostData(self, {choice = "turnOver", tos = {target} })
      return true
    end
  end,
  on_use = on_use,
})

skel:addEffect(fk.BeforeCardsMove, {
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not triggerable(player, target) then return false end
    -- 仅检测一次移动，因为懒得处理复杂
    for _, move in ipairs(data) do
      if move.from and move.moveReason == fk.ReasonDiscard and not move.from.dead then
        local choices = {}
        if #table.filter(move.moveInfo, function(info) return info.fromArea == Player.Hand end) == 2 then
          table.insert(choices, "discard2hand")
        end
        if #table.filter(move.moveInfo, function(info) return info.fromArea == Player.Equip end) == 1 then
          table.insert(choices, "discard1equip")
        end
        if #choices > 0 then
          event:setCostData(self, { choice = choices, tos = {move.from} })
          return true
        end
      end
    end
  end,
  on_use = on_use,
})



return skel
